import pprint
from readFile import ReadFile


class Originfreeze(object):

    def __init__(self, perFileData):
        '''
        :param perFileData: origin data of a Appfreeze file
        '''
        self.contents = perFileData
        self.path = perFileData[0]
        self.content = perFileData[1]
        self.sid_type = {
            "UB": "UI_BLOCK", "ABI": "APPLICATION_BLOCK_INPUT", "TB": "THREAD_BLOCK",
            "ALT": "APP_LIFECYCLE_TIMEOUT", "LT": "LIFECYCLE_TIMEOUT", "ND": "NO_DRAW",
        }
        self.stringid = self.getStringId()
        self.pid = self.getPid()
        self.msg = self.getMsg()
        self.peer_pid = self.getBinderCatcher()
        self.peer_trace = self.getPeerTrace()
        self.threadid = self.getThreadId()
        self.package_name = self.getPackageName()
        self.can_ignore = self.getIgnoreStatus()
        self.ori_solist = self.getOriSoList()
        self.stacktrace = self.getTrace()
        # testcase and not standard application package_status: 0, others package_status: 1
        self.package_status = self.getPackageStatus()

    def getStringId(self):
        for line in self.content:
            if line.startswith("Reason"):
                line = line.strip().lstrip("Reason:")
                return line
            if line.startswith('STRINGID'):
                line = line.strip().lstrip('STRINGID:')
                return line
        return None

    def getPid(self):
        for line in self.content:
            if line.startswith("PID"):
                return line.split(":")[-1]
        return None

    def getMsg(self):
        for line in self.content:
            if line.startswith('MSG'):
                return line
        return None

    def getBinderCatcher(self):
        status = 0
        for line in self.content:
            if status == 0:
                if line.startswith("BinderCatcher"):
                    status = 1
            elif status == 1:
                if line.strip().startswith(self.pid) and "code" in line and "wait" in line:
                    peer_pid = line.split(':')[1].split()[-1]
                    return peer_pid
            if "PeerBinder Stacktrace" in line:
                return None
        return None

    def getPeerTrace(self):
        status = 0
        peer_block = {}
        peer_so_list = []
        for line in self.content:
            if status == 0:
                if line.startswith(f'Pid:{self.peer_pid}'):
                    peer_block["pid"] = line
                    status = 1
            elif status == 1:
                if line.startswith(f'Process name'):
                    peer_block["pname"] = line
                if line.startswith(f'Tid:{self.peer_pid}'):
                    peer_block["tid"] = line
                    status = 2
            elif status == 2:
                if line.startswith('#'):
                    peer_so_list.append(line)
                else:
                    status = 3
            else:
                peer_block["so_list"] = peer_so_list
                return peer_block

    def getThreadId(self):
        if self.sid_type["UB"] in self.stringid:
            if not self.msg:
                return None
            else:
                if 'id' in self.msg:
                    id = self.msg.strip().split()[-1]
                    for i in id:
                        i: str
                        if not i.isnumeric():
                            return None
                    return id
                else:
                    return None
        elif self.sid_type["ABI"] in self.stringid:
            return self.pid
        elif self.sid_type["TB"] in self.stringid:
            return self.pid
        elif self.sid_type["ALT"] in self.stringid:
            return self.pid
        elif self.sid_type["LT"] in self.stringid:
            return self.pid
        elif self.sid_type["ND"] in self.stringid:
            return None
        else:
            if 'id' in self.msg:
                id = self.msg.strip().split()[-1]
                for i in id:
                    i: str
                    if not i.isnumeric():
                        return None
                return id
            else:
                return None

    def getIgnoreStatus(self):
        if self.stringid is not None and self.msg is not None:
            if 'NO_FOCUS_WINDOW' in self.stringid and 'launcher' not in self.msg:
                return True
            if 'NO_DRAW' in self.stringid and 'launcher' not in self.msg:
                return True
        else:
            return False

    def getPackageName(self):
        '''
        comment: 获取模块名
        :return:
        '''
        p_name = self.path.split('\\')[-1].split('-')[1].strip()
        if p_name == "LIFECYCLE_TIMEOUT":
            status = 0
            for idx in range(len(self.content)):
                curline: str = self.content[idx]
                if curline.startswith('PACKAGE_NAME') and status == 0:
                    if ':' in curline:
                        p_name = curline.split(':')[-1].strip()
                    elif '=' in curline:
                        p_name = curline.split('=')[-1].strip()
                    else:
                        p_name = curline.strip()
                    if p_name:
                        return p_name
                    else:
                        status = 1
                elif curline.startswith("PROCESS_NAME") and status == 1:
                    if ':' in curline:
                        p_name = curline.split(':')[-1].strip()
                    elif '=' in curline:
                        p_name = curline.split('=')[-1].strip()
                    else:
                        p_name = curline.strip()
                    if p_name:
                        return p_name
                    else:
                        status = 2
                elif curline.startswith("MSG") and status == 2:
                    if "ability:" in curline:
                        p_name = curline.split(":")[-1]
                        if '.MainAbility' in p_name:
                            p_name = p_name.split('.MainAbility')[0].strip()
                        else:
                            p_name = p_name.split(' ')[0].strip()
                        return p_name
                else:
                    pass
        return p_name

    def getOriSoList(self):
        status = 0
        ori_so_list = []
        for line in self.content:
            if status == 0:
                if line.startswith(f'Tid:{self.threadid}'):
                    status = 1
            elif status == 1:
                if line.startswith('#'):
                    ori_so_list.append(line)
                else:
                    status = 2
            else:
                return ori_so_list

    def getTrace(self):
        for line in self.content:
            line: str = line.strip()
            if line.startswith("at "):
                return line.split()[1]
            if "****" in line:
                return ''
        return ""

    def getPackageStatus(self):
        if self.package_name == '':
            return 0
        filter_list1 = ['ceshi', 'test', 'ix', "acts", "tencent"]
        if "contacts" not in self.package_name:
            for filter_str in filter_list1:
                if filter_str in self.package_name and '.' in self.package_name:
                    return 0
        filter_list2 = ["Browser", 'baseanimation', 'kikakeyboard', 'ouc', 'himovie', 'himusicdemo',
                        'adminprovisioning', 'callui', 'camera', 'contacts', 'contactsdataability',
                        'devicemanagerui', 'dlpmanager', 'download', 'filepicker', 'gameperceptio', 'launcher',
                        'medialibrary', 'medialibrarydata', 'mms', 'note', 'nweb', 'permissionmanager',
                        'photos', 'screenlock', 'screenshot', 'settings', 'faceauth', 'settingsdata', 'systemui',
                        'telephonydataability', 'backgroundtaskmgr', 'resources', 'systemres', 'airquality',
                        'clock', 'distributedcalc', 'ecg', 'flashlight', 'shopping', 'telephony']
        if "example" in self.package_name and '.' in self.package_name:
            if self.listNotMatchTarget(filter_list2, self.package_name):
                return 0
        return 1

    def listNotMatchTarget(self, ls, target):
        for i in ls:
            if i in target:
                return 0
        return 1
